using System;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Collections.Specialized;


namespace My.IdlConverter.Core.Parsers
{
    using Filters;

    public class InterfaceParser: ParserBase
    {
        public static readonly string InterfaceMethodRegex = @"virtual.*\s*=\s*0";

        public InterfaceParser()
            :base()
        {
        }
        ~InterfaceParser() { }

        public override object Parse(string target)
        {
            Interface interfaceObj = new Interface(Recognizer.GetDOMInterfaceName(target));

            string content = null;
            if (!Util.IOHelper.ReadToEnd(target, out content))
            {
                return null;
            }

            IPreprocessor<string> preprocessor = new InterfacePreprocessor(content);
            content = preprocessor.Process();

            ParseMethods(interfaceObj,content);

            Success = ( interfaceObj!=null );

            return interfaceObj;
        }

        private void ParseMethods(Interface interfaceObj, string content)
        {
            IParser methodParser = new MethodParser();

            Regex reg = new Regex(InterfaceMethodRegex);
            MatchCollection matchCol = reg.Matches(content);
            string methodEntry = null;

            foreach (Match nextMatch in matchCol)
            {
                methodEntry = nextMatch.Value;
                if (!Recognizer.RecognizeMethod(methodEntry))
                    continue;
                if (MethodModifier.IsAspiredMethod(methodEntry))
                {
                    Method methodObj = methodParser.Parse(methodEntry) as Method;
                    Debug.Assert(methodObj != null);
                    if (methodParser.Success)
                    {
                        methodObj.Parent = interfaceObj;
                        interfaceObj.Methods.Add(methodObj);

                        if (OverloadCollision != null)
                            OverloadCollision.CacheMethods.Add(methodObj);
                    }
                    else
                    {
                        Debug.Assert(false);
                    }
                }
            }
        }
    }
}
